package com.zzh.wechatpay.controller;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.zzh.wechatpay.config.WeChatConfig;
import com.zzh.wechatpay.domain.VideoOrder;
import com.zzh.wechatpay.dto.VideoOrderDto;
import com.zzh.wechatpay.service.VideoOrderService;
import com.zzh.wechatpay.utils.WXPayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;

/**
 * 订单接口
 */
@RestController
//@RequestMapping("/user/api/v1/order")
@RequestMapping("/api/v1/order")
public class OrderController {

    @Autowired
    private VideoOrderService videoOrderService;
    @Autowired
    private WeChatConfig weChatConfig;

    @GetMapping("add")
    public void saveOrder(@RequestParam(value = "video_id", required = true) int videoId,
                          HttpServletRequest request,
                          HttpServletResponse response) throws Exception {

        //String ip = IpUtils.getIpAddr(request);
        //int userId = request.getAttribute("user_id");
        //临时写死的配置
        int userId = 1;
        String ip = "120.25.1.43";
        VideoOrderDto videoOrderDto = new VideoOrderDto();
        videoOrderDto.setUserId(userId);
        videoOrderDto.setVideoId(videoId);
        videoOrderDto.setIp(ip);

        String codeUrl = videoOrderService.save(videoOrderDto);
        if (codeUrl == null) {
            throw new NullPointerException();
        }

        try (OutputStream out = response.getOutputStream()) {
            //生成二维码配置
            Map<EncodeHintType, Object> hints = new HashMap<>(2);
            //设置纠错等级
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
            //编码类型
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

            BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE, 400, 400, hints);
            MatrixToImageWriter.writeToStream(bitMatrix, "png", out);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 微信支付回调接口
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("order_callback")
    public void callBack(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //获取输入流,写入数据,并转换为有序map
        ServletInputStream inputStream = request.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        Map<String, String> xmlToMap = WXPayUtil.xmlToMap(sb.toString());
        SortedMap<String, String> sortedMap = WXPayUtil.getSortedMap(xmlToMap);
        //验证签名正确
        if (WXPayUtil.isCorrectSign(sortedMap, weChatConfig.getPayKey())) {
            //验证状态码成功
            if ("SUCCESS".equals(sortedMap.get("return_code"))) {
                String outTradeNo = sortedMap.get("out_trade_no");
                VideoOrder dbVideoOrder = videoOrderService.findByOutTradeNo(outTradeNo);
                //验证订单状态(具体判断逻辑看业务场景)
                if (dbVideoOrder != null && dbVideoOrder.getState() == 0) {
                    VideoOrder videoOrder = new VideoOrder();
                    videoOrder.setOpenid(sortedMap.get("openid"));
                    videoOrder.setOutTradeNo(outTradeNo);
                    videoOrder.setNotifyTime(new Date());
                    videoOrder.setState(1);
                    //数据库操作成功
                    int rows = videoOrderService.updateVideoOderByOutTradeNo(videoOrder);
                    if (rows == 1) {
                        //通知微信订单处理成功,响应成功数据给微信
                        response.setContentType("text/xml");
                        response.getWriter().println("success");
                        return;
                    }
                }
            }
        }
        //响应错误数据给微信
        response.setContentType("text/xml");
        response.getWriter().println("fail");
    }

}
